package io.gitee.mingbaobaba.security.plugin.oauth2.redis.repository;

import io.gitee.mingbaobaba.security.core.utils.JsonUtil;
import io.gitee.mingbaobaba.security.oauth2.domain.SecurityOauth2Client;
import io.gitee.mingbaobaba.security.oauth2.domain.SecurityOauth2Details;
import io.gitee.mingbaobaba.security.oauth2.repository.SecurityOauth2Repository;
import io.gitee.mingbaobaba.security.plugin.oauth2.redis.constants.SecurityOauth2RedisConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;


/**
 * <p>redis存储</p>
 *
 * @author yingsheng.ye
 * @version 1.0.0
 * @since 2023/8/29 10:09
 */
@Slf4j
public class SecurityOauth2RedisRepository implements SecurityOauth2Repository {

    private final StringRedisTemplate stringRedisTemplate;

    public SecurityOauth2RedisRepository(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public void saveAuthorizationCode(String authorizationCode, SecurityOauth2Client securityClientMode, long timeout) {
        String redisKey = MessageFormat.format(SecurityOauth2RedisConstant.AUTHORIZATION_CODE_KEY, authorizationCode);
        stringRedisTemplate.opsForValue().set(redisKey, JsonUtil.objectToJsonStr(securityClientMode), timeout, TimeUnit.SECONDS);
    }

    @Override
    public SecurityOauth2Client getClientModelByAuthorizationCode(String authorizationCode) {
        String redisKey = MessageFormat.format(SecurityOauth2RedisConstant.AUTHORIZATION_CODE_KEY, authorizationCode);
        String strJson = stringRedisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isBlank(strJson)) {
            return null;
        }
        return JsonUtil.jsonStrToObject(strJson, SecurityOauth2Client.class);
    }

    @Override
    public void removeAuthorizationCode(String authorizationCode) {
        String redisKey = MessageFormat.format(SecurityOauth2RedisConstant.AUTHORIZATION_CODE_KEY, authorizationCode);
        stringRedisTemplate.delete(redisKey);
    }

    @Override
    public boolean saveOauth2TokenDetails(SecurityOauth2Details securityOauth2Details, Long timeout) {
        String refreshRedisKey = MessageFormat.format(SecurityOauth2RedisConstant.REFRESH_TOKEN_KEY, securityOauth2Details.getRefreshToken());
        stringRedisTemplate.opsForValue().set(refreshRedisKey, securityOauth2Details.getAccessToken(), timeout, TimeUnit.SECONDS);
        String accessRedisKey = MessageFormat.format(SecurityOauth2RedisConstant.ACCESS_TOKEN_KEY, securityOauth2Details.getAccessToken());
        stringRedisTemplate.opsForValue().set(accessRedisKey, JsonUtil.objectToJsonStr(securityOauth2Details), timeout, TimeUnit.SECONDS);
        return true;
    }

    @Override
    public SecurityOauth2Details getOauth2DetailsByAccessToken(String accessToken) {
        String accessRedisKey = MessageFormat.format(SecurityOauth2RedisConstant.ACCESS_TOKEN_KEY, accessToken);
        String strJson = stringRedisTemplate.opsForValue().get(accessRedisKey);
        if (StringUtils.isBlank(strJson)) {
            return null;
        }
        return JsonUtil.jsonStrToObject(strJson, SecurityOauth2Details.class);
    }

    @Override
    public String accessTokenByRefreshToken(String refreshToken) {
        String redisKey = MessageFormat.format(SecurityOauth2RedisConstant.REFRESH_TOKEN_KEY, refreshToken);
        return stringRedisTemplate.opsForValue().get(redisKey);
    }

    @Override
    public Long refreshTokenTimeOut(String refreshToken) {
        String redisKey = MessageFormat.format(SecurityOauth2RedisConstant.REFRESH_TOKEN_KEY, refreshToken);
        return stringRedisTemplate.getExpire(redisKey);
    }
}
